package service

import (
	"duoke/context"
	"duoke/model"
	"duoke/tables"
	"duoke/utils/gconv"
	"duoke/utils/gmd5"
	"duoke/utils/gstr"
	"duoke/utils/orm"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/gogf/gf/v2/frame/g"
	"time"
)

var Account = new(accountService)

type accountService struct{}

// 账户登录
func (s *accountService) Login(username, password string) (*tables.Account, error) {
	account := new(tables.Account)
	has, err := orm.Db.Where("username=?", username).Or("phone=?", username).Get(account)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, errors.New("该账户不存在")
	}
	// 密码校验
	pwd, _ := gmd5.Encrypt(password + account.Salt)
	g.Dump(pwd)
	if account.Password != pwd {
		return nil, errors.New("密码不正确")
	}
	// 判断当前用户状态
	if account.State != 1 {
		return nil, errors.New("您的账号已被禁用,请联系管理员")
	}
	// 是否已过期
	if account.ExpireTime < gconv.Int(time.Now().Unix()) {
		return nil, errors.New("您的账号已过期,请联系管理员")
	}
	account.LastLoginTime = int(time.Now().Unix())
	account.LastLoginIp = context.Global.Ip
	// 更新登录时间、登录IP
	affected, err := orm.Db.ID(account.Id).Cols("last_login_ip", "last_login_time").Update(account)
	if affected == 0 {
		return nil, errors.New("账户登录信息更新失败")
	}
	if err != nil {
		return nil, err
	}
	return account, nil
}

// 账户信息
func (s *accountService) GetById(id int, field string) (*tables.Account, error) {
	account := new(tables.Account)
	has, err := orm.Db.ID(id).Cols(field).Get(account)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, errors.New("该账户不存在")
	}
	return account, nil
}

// 账户信息
func (s *accountService) Get(where string, field string) (*tables.Account, error) {
	account := new(tables.Account)
	has, err := orm.Db.Where(where).Cols(field).Get(account)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, errors.New("该用户不存在")
	}
	return account, nil
}

// 账户信息
func (s *accountService) GetInfo(id int) (*model.AccountInfo, error) {
	account := new(model.AccountInfo)
	has, err := orm.Db.ID(id).Get(account)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, errors.New("该账户不存在")
	}
	// 默认头像
	if account.Avatar == "" {
		account.Avatar = "https://himg.bdimg.com/sys/portrait/hotitem/wildkid/47"
	}
	return account, nil
}

// 账户信息
func (s *accountService) SaveInfo(id int, req model.ReqAccountInfo) error {
	account, err := s.GetById(id, "")
	if err != nil {
		return err
	}
	// 验证手机号码唯一性
	if req.Phone != account.Phone {
		total, err := orm.Db.Where("phone =?", req.Phone).Count(new(tables.Account))
		if err != nil {
			return err
		}
		if total > 0 {
			return errors.New("该手机号码已被注册过账户")
		}
	}
	// 密码加密
	if req.Password != "" {
		account.Password, _ = gmd5.Encrypt(req.Password + account.Salt)
	}
	account.Name = req.Name
	account.Avatar = req.Avatar
	account.Nickname = req.Nickname
	account.Phone = req.Phone
	_, err = orm.Db.ID(id).Cols("name", "avatar", "phone", "nickname", "password").Update(account)
	if err != nil {
		return err
	}
	return nil
}

// 新增/保存
func (s *accountService) Save(c *gin.Context, req model.ReqAccount) error {
	accountR, _ := Request.Account(c)
	if req.UseStorageAcid > 0 {
		req.UseStorageAcid = accountR.Id
	}
	if req.Id != 0 {
		account, err := s.GetById(req.Id, "")
		if err != nil {
			return err
		}
		// 验证账户唯一性
		if req.Username != account.Username {
			total, err := orm.Db.Where("username =?", req.Username).Count(new(tables.Account))
			if err != nil {
				return err
			}
			if total > 0 {
				return errors.New("该用户名已被注册过账户")
			}
		}
		// 验证手机号码唯一性
		if req.Phone != account.Phone {
			total, err := orm.Db.Where("phone =?", req.Phone).Count(new(tables.Account))
			if err != nil {
				return err
			}
			if total > 0 {
				return errors.New("该手机号码已被注册过账户")
			}
		}
		// 密码加密
		if req.Password != "" {
			req.Password, _ = gmd5.Encrypt(req.Password + account.Salt)
		} else {
			req.Password = account.Password
		}
		// 保存数据
		_, err = orm.Db.ID(req.Id).Cols("password", "phone", "name", "nickname", "avatar", "expire_time", "has_apps", "use_storage_acid").Update(req)
		if err != nil {
			return err
		}
	} else {
		// 验证账户唯一性
		total, err := orm.Db.Where("username =?", req.Username).Count(new(tables.Account))
		if err != nil {
			return err
		}
		if total > 0 {
			return errors.New("该用户名已被注册过账户")
		}
		// 验证手机号码唯一性
		total, err = orm.Db.Where("phone =?", req.Phone).Count(new(tables.Account))
		if err != nil {
			return err
		}
		if total > 0 {
			return errors.New("该手机号码已被注册过账户")
		}
		// 密码加密
		req.Salt = gstr.Random(6)
		if req.Password != "" {
			req.Password, _ = gmd5.Encrypt(req.Password + req.Salt)
		}
		// 保存数据
		_, err = orm.Db.Insert(req)
		if err != nil {
			return err
		}
	}
	return nil
}

// 列表
func (s *accountService) List(req model.ReqList) ([]tables.Account, int64, error) {
	// 分页
	offset := (req.PageNo - 1) * req.PageSize
	list := make([]tables.Account, 0)
	query := orm.Db.Desc("id").Where("id <>?", 1).Where("role =?", "account")
	if req.State != "" {
		query = query.Where("state =?", req.State)
	}
	if req.Keyword != "" {
		query = query.Where("username =? OR phone =? OR nickname =?", req.Keyword, req.Keyword, req.Keyword)
	}
	if req.IsExpire == "1" {
		query = query.Where("expire_time >?", time.Now().Unix())
	}
	if req.IsExpire == "0" {
		query = query.Where("expire_time <?", time.Now().Unix())
	}
	total, err := query.Limit(req.PageSize, offset).FindAndCount(&list)
	if err != nil {
		return nil, 0, err
	}
	return list, total, nil
}

// 列表
func (s *accountService) Del(req model.ReqIds) error {
	// 删除数据
	_, err := orm.Db.In("id", req.Ids).Delete(new(tables.Account))
	if err != nil {
		return err
	}
	return nil
}

// 状态
func (s *accountService) State(req model.ReqId) error {
	account, err := s.GetById(req.Id, "")
	if err != nil {
		return err
	}
	if account.State == 1 {
		account.State = 0
	} else {
		account.State = 1
	}
	_, err = orm.Db.ID(req.Id).Cols("state").Update(account)
	if err != nil {
		return err
	}
	return nil
}
